/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.cmd.identity;

import cn.easyplatform.entities.beans.project.ProjectBean;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.lang.Times;
import cn.easyplatform.studio.StudioException;
import cn.easyplatform.studio.cfg.SessionManager;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.dao.IdentityDao;
import cn.easyplatform.studio.interceptor.Command;
import cn.easyplatform.studio.interceptor.CommandContext;
import cn.easyplatform.studio.utils.SecurityUtils;
import cn.easyplatform.studio.utils.StudioUtil;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.vos.LoginUserVo;
import cn.easyplatform.studio.vos.ProjectRoleVo;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Sessions;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class LoginCmd implements Command<Object> {

	private String userId, password;

	public LoginCmd(String userId, String password) {
		this.userId = userId;
		this.password = password;
	}

	@Override
	public Object execute(CommandContext cc) {
		//获取用户
		IdentityDao dao = cc.getIdentityDao();
		LoginUserVo user = dao.getUser(userId);
		if (user == null)
			throw new StudioException(Labels.getLabel("user.not.found"));
		if (!user.getPassword().equals(
				SecurityUtils.getSecurePassword(password, user.getSalt()))) {
			int tryTimes = user.getLoginFailedTimes();
			tryTimes++;
			dao.updateTryTimes(userId, tryTimes, WebUtils.getRemoteAddr());
			int max = cc.getConfigAsInt("user.maxLoginFailedTimes");
			if (tryTimes >= max) {// 锁用户
				dao.updateState(userId, WebUtils.getRemoteAddr(),
						LoginUserVo.STATE_LOCK);
				throw new StudioException(Labels.getLabel("user.try.error"));
			}
			throw new StudioException(Labels.getLabel("user.password.error"));
		}
		// 检查用户有效期
		int remainingDays = 0;
		if (user.getValidDate() != null) {
			Date now = Times.toDay();
			if (now.before(user.getValidDate())) // 设置的有效开始日期还未到
				throw new StudioException(Labels.getLabel("user.invalid"));
			if (user.getValidDays() > 0) {// 是否过期
				int oneDay = 24 * 60 * 60 * 1000;
				Date when = new Date(user.getValidDate().getTime()
						+ user.getValidDays() * oneDay);
				if (now.after(when)) // 密码过期
					throw new StudioException(Labels.getLabel("user.invalid"));
				int days = cc.getConfigAsInt("user.caculateDaysRemaining");
				if (days > 0) {
					remainingDays = (int) ((now.getTime() - when.getTime()) / oneDay);
					if (remainingDays > days)// 如果剩余天数大于指定的天数，重置为零
						remainingDays = 0;
					if (remainingDays > 0)
						user.setRemainingDays(remainingDays);
				}
			}
		}
		SessionManager sm = cc.getSessionManager();
		int rs = sm.checkUser(user);
		if (rs > LoginUserVo.ONLINE_NONE) // 表示用户已存在
			return Labels.getLabel("user.has.login", new String[] { userId });
		//获取项目
		ProjectBean[] projects;
		String roleId = null;
		if (Strings.isBlank(user.getDefaultProject()) == false && user.getDefaultProject().split(",").length == 2) {
			String projectId = user.getDefaultProject().split(",")[0];
			roleId = user.getDefaultProject().split(",")[1];
			projects = dao.getProjectWithID(projectId, roleId, userId);
		} else {
			projects = dao.getProject(userId);
			if (projects.length > 0) {
				String roles = dao.getTopRole(projects[0].getId(), userId);
				if (Strings.isBlank(roles) == false && roles.split(",").length > 0) {
					List<String> roleList = Arrays.asList(roles.split(","));
					if (roleList.contains(LoginUserVo.UserType.DEV.getName())) {
						roleId = LoginUserVo.UserType.DEV.getName();
					} else {
						roleId = roleList.get(0);
					}
				}
			}
		}
		if (projects.length > 0) {
			if (roleId == null)
				throw new StudioException(Labels.getLabel("user.role.error"));
			//获取权限
			if (LoginUserVo.UserType.ADMIN.getName().equals(roleId) == false) {
				String access = dao.getRolePermissions(projects[0].getId(), roleId);
				if (Strings.isBlank(access))
					throw new StudioException(Labels.getLabel("user.role.permissions.error"));
				user.setAuthorization(StudioUtil.fromJson(access));
			}
			//获取所有项目所有权限
			List<ProjectRoleVo> projectRoleVos = dao.getAllProjectRole(userId);
			user.setRoleVoList(projectRoleVos);
			user.setRoleId(roleId);
		}
		user.setTimeout(cc.getConfigAsInt("user.timeToLive"));
		user.setLastAccessTime(new Date());
		//user.setTheme("atrovirens_c");
		dao.updateState(userId, WebUtils.getRemoteAddr(),
				LoginUserVo.STATE_ACTIVATED);
		Contexts.setUser(user);
		sm.setUser(user);
		user.setSession(Sessions.getCurrent());
		if (projects.length > 0) {
			if (projects.length > 1)
				return projects;
			Contexts.setProject(projects[0]);
		}
		return user;
	}
}
